﻿using ServiceStack.Caching;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Coments.Service
{
    public class RedisCacheManagerInstance
    {
        /// <summary>
        /// Redis哨兵集群
        /// </summary>
        static string[] ShangouRedisGroupSentinelIps
        {
            get { return (ConfigurationManager.AppSettings["ShangouRedisGroupSentinelIps"] ?? "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); }
        }

        /// <summary>
        /// Redis哨兵名称
        /// </summary>
        static string ShangouRedisGroupSentinelName
        {
            get { return ConfigurationManager.AppSettings["ShangouRedisGroupSentinelName"]; }
        }

        public static IRedisClient DefaultRedisCache
        {
            get
            {
                RedisSentinel sentinel = new RedisSentinel(ShangouRedisGroupSentinelIps, ShangouRedisGroupSentinelName);
                var pool = (PooledRedisClientManager)sentinel.Setup();
                return pool.GetClient();
            }
        }
    }

    public class RedisCacheManager
    {
        static string GetKey(string key)
        {
            return ConfigurationManager.AppSettings["CachePrefix"] + ":" + key;
        }

        /// <summary>
        /// Redis哨兵名称
        /// </summary>
        static int ListCount
        {
            get { return Convert.ToInt32(ConfigurationManager.AppSettings["ListCount"] ?? "10"); }
        }

        #region Redis缓存

        /// <summary>
        /// 获取Redis缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="key">key</param>
        /// <returns></returns>
        public static T GetCache<T>(string key)
        {
            try
            {
                key = GetKey(key);
                return RedisCacheManagerInstance.DefaultRedisCache.Get<T>(key);
            }
            catch
            {
                return default(T);
            }
        }

        /// <summary>
        /// 添加Redis缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="key">key</param>
        /// <param name="t">数据</param>
        /// <param name="minutes">时间(分)0永久</param>
        /// <param name="isRun">是否启用内存缓存</param>
        public static bool AddCache<T>(string key, T t, int minutes)
        {
            try
            {
                if (t == null) return false;
                key = GetKey(key);
                return RedisCacheManagerInstance.DefaultRedisCache.Set<T>(key, t, DateTime.Now.AddMinutes(minutes));
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 移除Redis缓存
        /// </summary>
        /// <param name="key">key</param>
        public static bool Remove(string key, bool isRun = false)
        {
            try
            {
                key = GetKey(key);
                return RedisCacheManagerInstance.DefaultRedisCache.Remove(key);
            }
            catch
            {
                return false;
            }
        }

        #endregion

        #region Store

        /// <summary>
        /// 获取Redis缓存
        /// </summary>
        /// <returns></returns>
        public static IList<T> GetStoreCache<T>()
        {
            try
            {
                var data = RedisCacheManagerInstance.DefaultRedisCache.As<T>();
                return data.GetAll();
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 添加Redis缓存
        /// </summary>
        /// <typeparam name="value">数据类型</typeparam>
        public static void AddStoreCache<T>(T value)
        {
            try
            {
                if (value == null) return;
                var data = RedisCacheManagerInstance.DefaultRedisCache.As<T>();
                data.Store(value);
            }
            catch
            {
                return;
            }
        }

        #endregion

        /// <summary>
        /// 获取Redis缓存
        /// </summary>
        /// <returns></returns>
        public static long GetListCount(string key)
        {
            try
            {
                key = GetKey(key);
                return RedisCacheManagerInstance.DefaultRedisCache.GetListCount(key);
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取Redis缓存
        /// </summary>
        /// <returns></returns>
        public static List<string> GetListCache(string key)
        {
            try
            {
                key = GetKey(key);
                var data = RedisCacheManagerInstance.DefaultRedisCache.GetAllItemsFromList(key);
                if (data != null)
                {
                    //data.Reverse();
                    return data.Take(ListCount).ToList();
                }
            }
            catch
            {

            }
            return null;
        }

        /// <summary>
        /// 添加Redis缓存
        /// </summary>
        /// <typeparam name="value">数据类型</typeparam>
        public static void AddListCache(string key, string value)
        {
            try
            {
                key = GetKey(key);
                if (value == null) return;
                var rows = RedisCacheManagerInstance.DefaultRedisCache.GetListCount(key);
                if (rows == ListCount)
                {
                    RedisCacheManagerInstance.DefaultRedisCache.DequeueItemFromList(key);//.RemoveStartFromList(key);
                }
                RedisCacheManagerInstance.DefaultRedisCache.EnqueueItemOnList(key, value);//.PushItemToList(key, value);
            }
            catch
            {
                return;
            }
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="isAll"></param>
        public static void RemoveListCache(string key, string value, bool isAll = false)
        {
            key = GetKey(key);
            if (isAll)
            {
                RedisCacheManagerInstance.DefaultRedisCache.RemoveAllFromList(key);
            }
            else
            {
                RedisCacheManagerInstance.DefaultRedisCache.RemoveItemFromList(key, value);
            }
        }
    }
}
